// mainly a hack from spandsp examples

#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
#include <spandsp.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <audiofile.h>
#include <inttypes.h>
#include <limits.h>
#include <tiffio.h>

#include "config.h"

// not sure of this
#define SAMPLES_PER_CHUNK 160


int mod_dtmf(char *file, char *digits)
{
    dtmf_tx_state_t gen;
    int16_t amp[16384];
    int len;
    AFfilehandle outhandle;
    AFfilesetup filesetup;
    int outframes;
    int add_digits;

    if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
    {
        fprintf(stderr, "    Failed to create file setup\n");
        exit(2);
    }
    afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
    afInitRate(filesetup, AF_DEFAULT_TRACK, 8000.0);
    //afInitCompression(filesetup, AF_DEFAULT_TRACK, AF_COMPRESSION_G711_ALAW);
    afInitFileFormat(filesetup, AF_FILE_RAWDATA);
    afInitChannels(filesetup, AF_DEFAULT_TRACK, 1);

    if ((outhandle = afOpenFile(file, "w", filesetup)) == AF_NULL_FILEHANDLE)
    {
        fprintf(stderr, "    Cannot open raw file '%s'\n", file);
        exit(2);
    }

    dtmf_tx_init(&gen);
    //dtmf_tx_set_level(&gen, -5, 0);
    //dtmf_tx_set_level(&gen, -10, 0);
    //dtmf_tx_set_timing(&gen, 100, 50);
    //dtmf_tx_set_timing(&gen, 50, 55);
    if (dtmf_tx_put(&gen, digits, -1))
        printf("Data generated needs more than the hardcoded max no. of digits. See dtmf.h\n");
    do
    {
      len = dtmf_tx(&gen, amp, 160);
      if (len > 0) {
        outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, amp, len);
      }
      //printf("len:%d\n", len);
    }
    while (len > 0);

    if (afCloseFile(outhandle) != 0)
    {
        fprintf(stderr, "Cannot close file '%s'\n", file);
        exit (2);
    }
    afFreeFileSetup(filesetup);

    return  0;
}

int demod_dtmf(const char *file, char *digits)
{
  int16_t amp[SAMPLES_PER_CHUNK]; // samples per chunk
    AFfilehandle inhandle;
    AFfilesetup filesetup;
    dtmf_rx_state_t dtmf_state;
    char buf[MAX_NUM_DIGITS+1];
    int actual;
    int samples;
    int total;

    dtmf_rx_init(&dtmf_state, NULL, NULL);
    dtmf_rx_parms(&dtmf_state, FALSE, -5, -5, -99);

    if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
    {
        fprintf(stderr, "    Failed to create file setup\n");
        exit(2);
    }
    afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
    afInitRate(filesetup, AF_DEFAULT_TRACK, 8000.0);
    //afInitCompression(filesetup, AF_DEFAULT_TRACK, AF_COMPRESSION_G711_ALAW);
    afInitFileFormat(filesetup, AF_FILE_RAWDATA);
    afInitChannels(filesetup, AF_DEFAULT_TRACK, 1);
    
    if ((inhandle = afOpenFile(file, "r", filesetup)) == AF_NULL_FILEHANDLE)
    {
        fprintf(stderr, "Cannot open file '%s'\n", file);
        exit(2);
    }
    
    total = 0;
    while ((samples = afReadFrames(inhandle, AF_DEFAULT_TRACK, amp, SAMPLES_PER_CHUNK)) > 0)
    {
        dtmf_rx(&dtmf_state, amp, samples);
        //printf("Status 0x%X\n", dtmf_rx_status(&dtmf_state));
        if ((actual = dtmf_rx_get(&dtmf_state, buf, MAX_NUM_DIGITS)) > 0) {
          memcpy(digits+total, buf, actual);
          //printf("Received '%s'\n", buf);
        }
        total += actual;
    }
    //printf("%d digits received\n", total);
    return total;
}



